package com.google.code.sms.filter;

import com.google.code.sms.service.SettingsService;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.File;
import java.io.IOException;

/**
 * This filter is executed very early in the filter chain. It verifies that the
 * SMS home directory (/var/sms) exists and is
 * writable. If not, a proper error message is given to the user.
 * <p/>
 * (The SMS home directory is usually created automatically, but a common
 * problem on Linux is that the Tomcat user does not have the necessary
 * privileges).
 *
 * @author Sindre Mehus
 */
public class BootstrapVerificationFilter implements Filter {

    private boolean smsHomeVerified = false;

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        // Already verified?
        if (smsHomeVerified) {
            chain.doFilter(req, res);
            return;
        }

        File home = SettingsService.getSMSHome();
        if (!directoryExists(home)) {
            error(res, "<p>The directory <b>" + home + "</b> does not exist. Please create it and make it writable, "
                    + "then restart the servlet container.</p>"
                    + "<p>(You can override the directory location by specifying -Dsms.home=... when "
                    + "starting the servlet container.)</p>");

        } else if (!directoryWritable(home)) {
            error(res, "<p>The directory <b>" + home + "</b> is not writable. Please change file permissions, "
                    + "then restart the servlet container.</p>"
                    + "<p>(You can override the directory location by specifying -Dsms.home=... when "
                    + "starting the servlet container.)</p>");

        } else {
            smsHomeVerified = true;
            chain.doFilter(req, res);
        }
    }

    private boolean directoryExists(File dir) {
        return dir.exists() && dir.isDirectory();
    }

    private boolean directoryWritable(File dir) {
        try {
            File tempFile = File.createTempFile("test", null, dir);
            tempFile.delete();
            return true;
        } catch (IOException x) {
            return false;
        }
    }

    private void error(ServletResponse res, String error) throws IOException {
        ServletOutputStream out = res.getOutputStream();
        out.println("<html>"
                + "<head><title>SMS Error</title></head>"
                + "<body>"
                + "<h2>SMS Error</h2>"
                + error
                + "</body>"
                + "</html>");
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}
